package com.hemerasolutions.v2trainer.model.training.statistic;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;

import com.hemerasolutions.v2trainer.model.base.BaseModel;
import com.hemerasolutions.v2trainer.model.exercise.intensity.Intensity;
import com.hemerasolutions.v2trainer.model.exercise.intensity.IntensityZone;
import com.hemerasolutions.v2trainer.model.unit.volume.VolumeType;
import com.hemerasolutions.v2trainer.util.Utility;

@Entity
public class Statistic extends BaseModel {

	private static final long serialVersionUID = 1L;

    @Column
	private double value;

    @ManyToOne
    private TrainingStatistic stepStatistic;
    
	@ManyToOne
	private StatisticUnit statisticUnit;

	public Statistic() {
		super();
	}


	public Statistic(TrainingStatistic stepStatistic, StatisticUnit statisticUnit) {
		this();
		this.stepStatistic = stepStatistic;
		this.statisticUnit = statisticUnit;
	}



	public Statistic(TrainingStatistic stepStatistic, Statistic other) {
		this();
		this.statisticUnit = other.statisticUnit;
		this.stepStatistic = stepStatistic;
		this.value = other.value;
	}

	
	public void multiply(int multiplier) {
		this.value = value * multiplier;
	}
	

	public void calcStatistic(){
		switch(this.statisticUnit.getUnitType()){
			case StatisticUnit.SU_TYPE_A:
				this.value = this.calcAuA();
				break;
			case StatisticUnit.SU_TYPE_B:
				this.value = this.calcAuB();
				break;
			case StatisticUnit.SU_TYPE_C:
				this.value = this.calcAuC();
				break;
			case StatisticUnit.SU_TYPE_D:
				this.value = this.calcAuD();
				break;
			case StatisticUnit.SU_TYPE_E:
				this.value = this.calcAuE();
				break;
			case StatisticUnit.SU_TYPE_F:
				this.value = this.calcAuF();
				break;
			
			default:
				this.value = 0;
				break;
			
				
		}
			
	}



	private int calcAuF() {
		int au = 0;

		
		return au;
	}

	private int calcAuE() {
		IntensityZone iz = this.getStepStatistic().getIntensityZone(); 
		int au = 0;

		
		if(iz != null ){
			for(Intensity it:iz.getIntensitys()){
				if(it.getIntensityUnit().getName().equals("IU_FC")){
					au = (int) ((it.getLowValue() +  it.getHighValue()) /2);					
					au = (int) au * ((Long)iz.getUaFactor()).intValue();
				}
			}
		}
		
		return au;
	}

	private int calcAuD() {
		IntensityZone iz = this.getStepStatistic().getIntensityZone(); 
		VolumeType vt = this.getStepStatistic().getVolumeType(); 
		int au = 0;

		
		if(iz != null && vt != null ){
			if(vt.getName().equals("V_REPETITION")){
				au = (int)(iz.getUaFactor());
				au = (int)(au * this.getStepStatistic().getValue());					
			}
		}
		
		return au;
	}

	private int calcAuC() {
		int au = 0;

		IntensityZone iz = this.getStepStatistic().getIntensityZone(); 
		long mill = Utility.dateToLong(this.getStepStatistic().getActionTime());
		
	
		if(mill != 0 && iz != null && iz.getUaFactor() != 0){
			au = (int) (mill/1000 * iz.getUaFactor());
		}
		
		return au;
	}

	private int calcAuB() {
		int au = 0;
		
		IntensityZone iz = this.getStepStatistic().getIntensityZone(); 
		VolumeType vt = this.getStepStatistic().getVolumeType();
		
		if(iz != null && iz.getLowRpe() != null && iz.getHighRpe() != null && vt != null){
			if(vt.getName().equals("V_REPETITION")){
				au = (int)(iz.getLowRpe().getValue() +  iz.getHighRpe().getValue()) / 2;
				au = (int)(au * this.getStepStatistic().getValue());		
			}else if(iz.getAverageSpeed() != 0){
				au = (int)(iz.getLowRpe().getValue() +  iz.getHighRpe().getValue()) / 2;
				au = (int)(au * iz.getAverageSpeed());		
			}		
		}

		return au;
	}

	private int calcAuA() {
		int au = 0;

		IntensityZone iz = this.getStepStatistic().getIntensityZone(); 
		
		long mill = Utility.dateToLong(this.getStepStatistic().getActionTime());
		
		
		if(iz != null && iz.getLowRpe() != null && iz.getHighRpe() != null){
			au = (int)(iz.getLowRpe().getValue() +  iz.getHighRpe().getValue()) / 2;
			au = (int)(au * (mill / 1000 )) ;	
			return au;
		}else{
			return au;
		}
	}
	
	public void sum(Statistic other) {
		this.value = this.value + other.value;
	}

	public TrainingStatistic getStepStatistic() {
		return stepStatistic;
	}

	public void setStepStatistic(TrainingStatistic stepStatistic) {
		this.stepStatistic = stepStatistic;
	}

	public StatisticUnit getStatisticUnit() {
		return statisticUnit;
	}

	public void setStatisticUnit(StatisticUnit statisticUnit) {
		this.statisticUnit = statisticUnit;
	}
	
	public double getValue() {
		return value;
	}

	public void setValue(double value) {
		this.value = value;
	}


	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result
				+ ((statisticUnit == null) ? 0 : statisticUnit.hashCode());
		result = prime * result
				+ ((stepStatistic == null) ? 0 : stepStatistic.hashCode());
		return result;
	}


	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Statistic other = (Statistic) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (statisticUnit == null) {
			if (other.statisticUnit != null)
				return false;
		} else if (!statisticUnit.equals(other.statisticUnit))
			return false;
		if (stepStatistic == null) {
			if (other.stepStatistic != null)
				return false;
		} else if (!stepStatistic.equals(other.stepStatistic))
			return false;
		return true;
	}


	@Override
	public String toString() {
		return "Statistic [id=" + id + ", stepStatistic=" + stepStatistic
				+ ", statisticUnit=" + statisticUnit + "]";
	}
	




}
